package com.tarena.lbs.business.servcie.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.dto.AttachDTO;
import com.tarena.lbs.attach.pojo.param.AttachQRParam;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.attach.pojo.query.AttachQuery;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.dao.repository.BusinessRepository;
import com.tarena.lbs.business.dao.repository.StoreESRepository;
import com.tarena.lbs.business.dao.repository.StoreRepository;
import com.tarena.lbs.business.dao.repository.impl.StoreChainRepositoryImpl;
import com.tarena.lbs.business.pojo.param.StoreParam;
import com.tarena.lbs.business.pojo.param.UserLocationParam;
import com.tarena.lbs.business.pojo.po.BusinessPO;
import com.tarena.lbs.business.pojo.po.StoreChainPO;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.po.StoreSearchPO;
import com.tarena.lbs.business.pojo.query.AreaStoreQuery;
import com.tarena.lbs.business.pojo.query.StoreChainQuery;
import com.tarena.lbs.business.pojo.query.StoreQuery;
import com.tarena.lbs.business.pojo.vo.BusinessVO;
import com.tarena.lbs.business.pojo.vo.PictureVO;
import com.tarena.lbs.business.pojo.vo.StoreChainVO;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.servcie.StoreService;
import com.tarena.lbs.common.enums.BusinessTypeEnum;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StoreServiceImpl implements StoreService {
    @Autowired
    private StoreRepository storeRepository;

    @Autowired
    private BusinessRepository businessRepository;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private AttachApi attachApi;
    @Autowired
    private StoreESRepository storeESRepository;

    @Autowired
    private StoreChainRepositoryImpl storeChainRepository;

    @Override
    public void save(StoreParam param) throws BusinessException {
        UserPrinciple principle = AuthenticationContextUtils.get();
        if (principle != null) {
            if (principle.getRole() == Roles.SHOP) {
                if (businessRepository.getById(param.getBusinessId()) != null) {
                    StorePO storePO = new StorePO();
                    BeanUtils.copyProperties(param, storePO);
                    storePO.setStoreLongitude(param.getLongitude());
                    storePO.setStoreLatitude(param.getLatitude());
                    storePO.setCreateTime(new Date());
                    List<String> storeImageIds = param.getStoreImagesIds();
                    String storeImagesId = null;
                    for (String storeImageId : storeImageIds) {
                        log.debug("门店图片id:{}",storeImageId);
                        if (storeImagesId == null){
                            storeImagesId = storeImageId;
                        }else {
                            storeImagesId = storeImagesId + "," + storeImageId;
                        }
                    }
                    log.debug("门店图片id:{}",storeImagesId);
                    storePO.setStoreImagesId(storeImagesId);
                    log.debug("保存门店信息:{}",storePO);
                    storeRepository.save(storePO);

                    //生成店铺二维码
                    if(storeChainRepository.getByStoreId(storePO.getId())==null){
                        String Link = "https://www.baidu.com";
                        AttachQRParam attachQRParam = new AttachQRParam();
                        attachQRParam.setContent(Link);
                        attachQRParam.setBusinessType(BusinessTypeEnum.SHOP_QR.getType());
                        attachQRParam.setBusinessId(storePO.getId());
                        attachApi.generateQrCode(attachQRParam);

                        //查询二维码ID
                        AttachQuery attachQueryQR = new AttachQuery();
                        attachQueryQR.setBusinessId(storePO.getId());
                        attachQueryQR.setBusinessType(BusinessTypeEnum.SHOP_QR.getType());
                        List<AttachDTO> attachDTOList = attachApi.getAttachInfo(attachQueryQR);
                        String linkImage = attachDTOList.get(0).getId().toString();

                        StoreChainPO storeChainPO = new StoreChainPO();
                        storeChainPO.setStoreId(storePO.getId());
                        storeChainPO.setLink(Link);
                        storeChainPO.setLinkImage(linkImage);
                        storeChainPO.setLinkStatus(1);
                        storeChainPO.setCreateTime(new Date());
                        log.debug("保存门店链信息:{}",storeChainPO);
                        storeChainRepository.save(storeChainPO);
                    }

                    //绑定图片前先解绑
                    //解绑图片
                    if (storePO.getStoreImagesId() != null){
                        log.info("解绑图片");
                        //解绑图片
                        AttachQuery attachQuery = new AttachQuery();
                        attachQuery.setBusinessId(storePO.getId());
                        attachQuery.setBusinessType(BusinessTypeEnum.STORE.getType());
                        attachApi.deleteBusinessAttach(attachQuery);
                    }
                    //解绑logo
                    if (storePO.getStoreLogo() != null){
                        AttachQuery attachQuery = new AttachQuery();
                        attachQuery.setBusinessId(storePO.getId());
                        attachQuery.setBusinessType(BusinessTypeEnum.SHOP_LOGO.getType());
                        attachApi.deleteBusinessAttach(attachQuery);
                    }
                    //更新门店图片
                    log.info("绑定图片");
                    List<PicUpdateParam> picParams = new ArrayList<>();
                    List<String> storeImagesIds = param.getStoreImagesIds();
                    log.debug("门店图片id:{}",storeImagesIds);
                    //List<Integer> imgIdList = Arrays.stream(storeImagesIds.get(0).split(",")).map(Integer::parseInt).collect(Collectors.toList());
                    //封装图片更新参数
                    storeImagesIds.forEach(imgId->{
                        PicUpdateParam picParam = new PicUpdateParam();
                        picParam.setId(Integer.parseInt(imgId));
                        picParam.setBusinessType(BusinessTypeEnum.STORE.getType());
                        picParam.setBusinessId(storePO.getId());
                        log.debug("封装信息picParam:{}",picParam);
                        picParams.add(picParam);
                    });
                    attachApi.batchUpdateBusiness(picParams);

                    //更新店铺Logo
                    String shopLogo = param.getStoreLogo();
                    log.debug("店铺Logo:{}",shopLogo);
                    if (shopLogo != null){
                        //List<Integer> shopLogoIdList = Arrays.stream(shopLogo.split(",")).map(Integer::parseInt).collect(Collectors.toList());
                        //封装图片更新参数
                        PicUpdateParam picParam = new PicUpdateParam();
                        picParam.setId(Integer.parseInt(shopLogo));
                        picParam.setBusinessType(BusinessTypeEnum.SHOP_LOGO.getType());
                        picParam.setBusinessId(storePO.getId());
                        log.debug("封装信息picParam:{}",picParam);
                        picParams.add(picParam);
                        attachApi.batchUpdateBusiness(picParams);
                    }


                    StoreSearchPO storeSearchPO = new StoreSearchPO();
                    storeSearchPO.setBusinessId(storePO.getBusinessId());
                    storeSearchPO.setStoreName(storePO.getStoreName());
                    storeSearchPO.setLocation(storePO.getStoreLocation());
                    log.debug("ES保存信息:{}",storeSearchPO);
                    storeESRepository.save(storeSearchPO);
                } else {
                    throw new BusinessException("-3", "商家不存在");
                }
            } else {
                throw new BusinessException("-2", "认证失败");
            }
        } else {
            throw new BusinessException("-1", "请先登录");
        }
    }



    @Override
    public PageResult<StoreVO> pageList(StoreQuery query) throws BusinessException {
        UserPrinciple principle = AuthenticationContextUtils.get();
        if (principle != null){
            if (principle.getRole() == Roles.SHOP||principle.getRole() == Roles.ADMIN||principle.getRole() == Roles.USER){
                AdminDto adminDto = userApi.getAdminById(principle.getId());
                //通过调用用户获取商家信息
                BusinessPO businessPO = new BusinessPO();
                if (principle.getRole() == Roles.SHOP){
                    businessPO = businessRepository.getById(adminDto.getBusinessId());
                }else {
                    businessPO = businessRepository.getById(query.getBusinessId());
                }

                if (principle.getRole() == Roles.SHOP){

                    if (businessPO == null){
                        throw new BusinessException("-4","商家不存在");
                    }
                }

                query.setBusinessId(businessPO.getId());
                // 创建一个新的分页结果对象，用于存储最终的分页查询结果
                PageResult<StoreVO> voPage = new PageResult<>();
                //total objects pageNo pageSize totalPage
                // 调用 businessRepository 的 pagesList 方法进行分页查询，获取包含商家持久化对象的分页信息
                PageInfo<StorePO> pageInfo = storeRepository.pagesList(query);
                //pageNo pageSize total
                // 将分页信息中的页码设置到分页结果对象中
                voPage.setPageNo(pageInfo.getPageNum());
                // 将分页信息中的每页数量设置到分页结果对象中
                voPage.setPageSize(pageInfo.getPageSize());
                // 将分页信息中的总记录数设置到分页结果对象中
                voPage.setTotal(pageInfo.getTotal());
                // 声明一个存储管理员视图对象的列表
                List<StoreVO> vos = null;
                // 从分页信息中获取商家持久化对象列表
                List<StorePO> pos = pageInfo.getList();
                // 判断持久化对象列表是否不为空
                if (CollectionUtils.isNotEmpty(pos)) {
                    vos = pos.stream().map(po -> {
                        StoreVO vo = new StoreVO();
                        org.springframework.beans.BeanUtils.copyProperties(po, vo);
                        return vo;
                    }).collect(Collectors.toList());
                }
                voPage.setObjects(vos);
                return voPage;
            }else {
                throw new BusinessException("-2","认证失败");
            }
        }else {
            throw new BusinessException("-1","请先登录");
        }
    }

    @Override
    public PageResult<StoreVO> areaPageList(AreaStoreQuery query) throws BusinessException {
        UserPrinciple principle = AuthenticationContextUtils.get();
        if (principle != null){
            // 通过调用用户服务UserApi获取账号信息得到商家ID，而后通过区域id列表和商家id查询店铺列表
            AdminDto adminDto = userApi.getAdminById(principle.getId());
            // 创建一个新的分页结果对象，用于存储最终的分页查询结果
            PageResult<StoreVO> voPage = new PageResult<>();
            //total objects pageNo pageSize totalPage
            // 调用 businessRepository 的 pagesList 方法进行分页查询，获取包含商家持久化对象的分页信息
            PageInfo<StorePO> pageInfo = storeRepository.areaPagesList(query, adminDto.getBusinessId());
            //pageNo pageSize total
            // 将分页信息中的页码设置到分页结果对象中
            voPage.setPageNo(pageInfo.getPageNum());
            // 将分页信息中的每页数量设置到分页结果对象中
            voPage.setPageSize(pageInfo.getPageSize());
            // 将分页信息中的总记录数设置到分页结果对象中
            voPage.setTotal(pageInfo.getTotal());
            // 声明一个存储管理员视图对象的列表
            List<StoreVO> vos = null;
            // 从分页信息中获取商家持久化对象列表
            List<StorePO> pos = pageInfo.getList();
            // 判断持久化对象列表是否不为空
            if (CollectionUtils.isNotEmpty(pos)) {
                vos = pos.stream().map(po -> {
                    StoreVO vo = new StoreVO();
                    org.springframework.beans.BeanUtils.copyProperties(po, vo);
                    return vo;
                }).collect(Collectors.toList());
            }
            voPage.setObjects(vos);
            return voPage;
        }else {
            throw new BusinessException("-1","请先登录");
        }
    }

    @Override
    public void location(UserLocationParam param) {
        // 参数校验
        if (param == null) {
            log.warn("用户位置参数为空");
            return;
        }
        
        if (param.getLatitude() == null || param.getLongitude() == null) {
            log.warn("用户位置信息不完整: latitude={}, longitude={}", param.getLatitude(), param.getLongitude());
            return;
        }
        
        try {
            // 调用仓储层查询附近店铺
            List<StoreVO> nearbyStores = storeRepository.findNearbyStores(param);
            log.info("查询到{}个附近店铺", nearbyStores.size());
            
            // TODO: 在这里实现推送逻辑
            // 例如：将附近店铺列表推送给用户
            // 可以使用WebSocket、消息队列等方式实现推送
            // 伪代码示例：
            // pushService.pushToUser(param.getUserId(), nearbyStores);
            
            // 循环处理每个店铺（如果需要）
            for (StoreVO store : nearbyStores) {
                log.debug("附近店铺: ID={}, 名称={}", store.getId(), store.getStoreName());
                // 可以在这里添加对每个店铺的处理逻辑
            }
        } catch (Exception e) {
            log.error("查询附近店铺时发生异常: ", e);
        }
    }

    @Override
    public StoreVO detail(Integer id) {
        log.debug("查询店铺详情业务处理,入参:{}",id);
        StoreVO vo = new StoreVO();
        StorePO po = storeRepository.getById(id);
        String logoUrl = null;
        AttachQuery lQuery = new AttachQuery();
        lQuery.setBusinessId(id);
        lQuery.setBusinessType(BusinessTypeEnum.SHOP_LOGO.getType());
        log.debug("查询店铺logo参数:{}",lQuery);
        List<AttachDTO> logoAttachInfo = attachApi.getAttachInfo(lQuery);
        log.debug("查询店铺logo信息:{}",logoAttachInfo);
        logoUrl ="http://localhost:8090/static/"+ logoAttachInfo.get(0).getFileUuid();

        // 处理店铺图片
        AttachQuery pQuery = new AttachQuery();
        pQuery.setBusinessId(id);
        pQuery.setBusinessType(BusinessTypeEnum.STORE.getType());
        log.debug("查询店铺图片参数:{}",pQuery);
        List<AttachDTO> picAttachInfo = attachApi.getAttachInfo(pQuery);
        log.debug("查询店铺图片信息:{}",picAttachInfo);
        // 处理店铺图片
        List<PictureVO> pictureVOS = new ArrayList<>();
        for(AttachDTO attachDTO : picAttachInfo){
            PictureVO pictureVO = new PictureVO();
            pictureVO.setId(attachDTO.getId());
            pictureVO.setImage("http://localhost:8090/static/" + attachDTO.getFileUuid());
            pictureVOS.add(pictureVO);
        }
        log.debug("查询PO:{}",po);
        if (po != null){
            org.springframework.beans.BeanUtils.copyProperties(po, vo);
        }
        vo.setStoreLogo(logoUrl);
        vo.setPictureVOS(pictureVOS);
        log.debug("返回VO:{}",vo);
        return vo;
    }

    @Override
    public PageResult<StoreChainVO> getChain(StoreChainQuery query) {
        log.debug("查询店铺二维码列表业务处理,入参:{}",query);
        // 调用仓储层查询店铺二维码列表
        PageInfo<StoreChainPO> pageInfo = storeRepository.getChain(query);
        // 创建一个新的分页结果对象，用于存储最终的分页查询结果
        PageResult<StoreChainVO> voPage = new PageResult<>();
        // 将分页信息中的页码设置到分页结果对象中
        voPage.setPageNo(pageInfo.getPageNum());
        // 将分页信息中的每页数量设置到分页结果对象中
        voPage.setPageSize(pageInfo.getPageSize());
        // 将分页信息中的总记录数设置到分页结果对象中
        voPage.setTotal(pageInfo.getTotal());
        // 声明一个存储店铺二维码视图对象的列表
        List<StoreChainVO> vos = null;
        // 从分页信息中获取店铺二维码持久化对象列表
        List<StoreChainPO> pos = pageInfo.getList();
        // 判断持久化对象列表是否不为空
        if (CollectionUtils.isNotEmpty(pos)) {
            vos = pos.stream().map(po -> {
                StoreChainVO vo = new StoreChainVO();
                BeanUtils.copyProperties(po, vo);
                vo.setStoreName(storeRepository.getById(po.getStoreId()).getStoreName());
                vo.setStoreAddress(storeRepository.getById(po.getStoreId()).getStoreLocation());
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }

    @Override
    public void delete(Integer id) {
        log.debug("删除店铺业务处理,入参:{}",id);
        storeRepository.delete(id);
    }
}
